import { Tabs } from 'antd'
import { connect } from 'dva'

import { confirmBillApi } from '@/api/pcs/pcsBillManage'
import AekButton from '@/components/AekButton'
import AekLinkButton from '@/components/AekLinkButton'
import AekTable from '@/components/AekTable'
import PageLayout from '@/components/PageLayout'
import SearchForm from '@/components/SearchForm'
import { namespace } from '@/models/pcs/pcsBillManage'
import { getPagination, message, modal } from '@/utils/antdHelper'
import { add, subtract } from '@/utils/calculate'
import { formatDate, formatMoneyNum } from '@/utils/displayHelper'
import { getBasicFn } from '@/utils/dvaUtil'
import {
  PAY_STATUS_ENUM,
  PCS_BILL_MANAGE_TAB_ENUM,
  PCS_BILL_TYPE_ENUM,
  PCS_COMBO_TYPE_ENUM,
  PCS_COMPANION_PERIOD_ENUM,
} from '@/utils/enum'
import { requestWithTry } from '@/utils/request'

import DetailDrawer from '../pcsCompanionOrder/components/DetailDrawer'
import { PcsStatementDetailDrawer } from '../pcsStatementManage/pcsStatementDetail'

import CreateBillModal from './components/CreateBillModal'

/** 陪护 - 账单管理 */
const Index = ({ modelState, loading }) => {
  const {
    activeKey,
    searchParams,
    pageList = [],
    pagination,
    canConfirm,
    canCreate,
    totalCount = 0,
    totalBillAmount = 0,
    totalNursingAmount = 0,
    totalServiceCharge = 0,
    selectedRows = [],
    selectedRowKeys = [],
  } = modelState
  const { toAction, getLoading } = getBasicFn({ namespace, loading })

  const onActiveKeyChange = activeKey => {
    toAction({ activeKey, searchParams: {} })
    toAction({ pagination: { current: 1 } }, true)
    toAction('getPageList')
  }

  const selectedBillFee = add(...selectedRows.map(({ billTotalAmount = 0 }) => billTotalAmount))
  const selectedNurseFee = add(...selectedRows.map(({ nursingAmount = 0 }) => nursingAmount))
  const selectedServiceFee = add(...selectedRows.map(({ serviceCharge = 0 }) => serviceCharge))

  /** @type {import("@/components/SearchForm").SearchFormProps} */
  const searchProps = {
    searchParams,
    formData: [
      { field: 'billNo', label: '账单号码', component: { name: 'Input' } },
      { field: 'orderNo', label: '订单号码', component: { name: 'Input' } },
      { field: 'patientName', label: '患者姓名', component: { name: 'Input' } },
      { field: 'nursingWorkersName', label: '护工姓名', component: { name: 'Input' } },
      {
        field: 'billType',
        label: '账单类型',
        component: {
          name: 'Select',
          props: {
            options: PCS_BILL_TYPE_ENUM.options,
          },
        },
      },
      {
        exclude: activeKey === PCS_BILL_MANAGE_TAB_ENUM.WAIT_CONFIRM,
        field: 'payStatus',
        label: '支付状态',
        component: {
          name: 'Select',
          props: {
            options: PAY_STATUS_ENUM.options,
          },
        },
      },
      { field: 'orderCreateDate', label: '工单创建日期', component: { name: 'RangePicker' } },
      { field: 'serviceDate', label: '服务日期', component: { name: 'RangePicker' } },
    ],
    onSearch: values => {
      toAction({ searchParams: values })
      toAction({ pagination: { current: 1 } }, true)
      toAction('getPageList')
    },
  }

  /** @type {import("@/components/AekTable").AekTableProps} */
  const tableProps = {
    configKey: `${namespace}-${activeKey}`,
    rowKey: 'id',
    loading: getLoading('getPageList'),
    dataSource: pageList,
    pagination:
      activeKey === PCS_BILL_MANAGE_TAB_ENUM.WAIT_CONFIRM
        ? false
        : getPagination(pagination, (current, pageSize) => {
            toAction('getPageList', { current, pageSize })
          }),
    beforePagination:
      activeKey === PCS_BILL_MANAGE_TAB_ENUM.WAIT_CONFIRM ? (
        <span>
          <span className='mr40px'>{`已选数量: ${selectedRows.length}`}</span>
          <span className='mr40px'>
            已选账单费用: {<span className='c-money'>{formatMoneyNum(selectedBillFee || 0)}</span>}
          </span>
          <span className='mr40px'>
            已选护工费用: {<span className='c-money'>{formatMoneyNum(selectedNurseFee || 0)}</span>}
          </span>
        </span>
      ) : (
        <span>
          <span className='mr40px'>{`合计数量: ${totalCount}`}</span>
          <span className='mr40px'>
            合计账单费用: {<span className='c-money'>{formatMoneyNum(totalBillAmount || 0)}</span>}
          </span>
          <span className='mr40px'>
            合计护工费用: {<span className='c-money'>{formatMoneyNum(totalNursingAmount || 0)}</span>}
          </span>
        </span>
      ),
    columns: [
      { dataIndex: 'billNo', title: '账单号码', width: 180 },
      {
        exclude: activeKey !== PCS_BILL_MANAGE_TAB_ENUM.CONFIRMED,
        dataIndex: 'statementNo',
        title: '结算单号',
        render: (text, row) => (
          <AekLinkButton
            onClick={() => {
              PcsStatementDetailDrawer.PromiseThen({
                id: row.statementId,
              })
            }}
          >
            {text}
          </AekLinkButton>
        ),
      },
      {
        exclude: activeKey !== PCS_BILL_MANAGE_TAB_ENUM.CONFIRMED,
        dataIndex: 'payStatus',
        title: '支付状态',
        render: text => PAY_STATUS_ENUM.getText(text),
      },
      {
        dataIndex: 'orderNo',
        title: '订单号码',
        render: (text, record) => (
          <AekLinkButton
            onClick={() => {
              DetailDrawer.PromiseThen({ id: record.orderId, hideOperate: true })
            }}
          >
            {text}
          </AekLinkButton>
        ),
      },
      { dataIndex: 'patientName', title: '患者姓名' },
      { dataIndex: 'inpatientWardName', title: '地点' },
      { dataIndex: 'companionComboName', title: '套餐名称' },
      { dataIndex: 'comboType', title: '套餐类型', enum: PCS_COMBO_TYPE_ENUM },
      { dataIndex: 'nursingWorkersName', title: '护工姓名' },
      { dataIndex: 'chargingStandard', title: '收费标准' },
      { dataIndex: 'nursingWorkerSettlement', title: '护工结算' },
      { dataIndex: 'orderCreateTime', title: '工单创建时间', isDateTime: true },
      {
        key: 'startDate',
        title: '服务开始时间',
        width: 160,
        render: row => `${formatDate(row.startDate)} ${PCS_COMPANION_PERIOD_ENUM.getText(row.startPeriod)}`,
      },
      {
        key: 'endDate',
        title: '服务结束时间',
        width: 160,
        render: row => `${formatDate(row.endDate)} ${PCS_COMPANION_PERIOD_ENUM.getText(row.endPeriod)}`,
      },
      {
        dataIndex: 'serviceDays',
        title: '服务时长',
        render: text => `${text}天`,
      },
      { dataIndex: 'billType', title: '账单类型', enum: PCS_BILL_TYPE_ENUM },
      { exclude: activeKey !== PCS_BILL_MANAGE_TAB_ENUM.CONFIRMED, dataIndex: 'confirmUserName', title: '确认人' },
      {
        exclude: activeKey !== PCS_BILL_MANAGE_TAB_ENUM.CONFIRMED,
        dataIndex: 'confirmTime',
        title: '确认时间',
        isDateTime: true,
      },
      { dataIndex: 'billTotalAmount', title: '账单费用', fixed: 'right', isMoney: true },
      { dataIndex: 'payCommission', title: '支付手续费', fixed: 'right', isMoney: true },
      { dataIndex: 'payAmount', title: '已支付费用', fixed: 'right', isMoney: true },
      { dataIndex: 'nursingAmount', title: '护工费用', fixed: 'right', isMoney: true },
    ],
    rowSelection: activeKey === PCS_BILL_MANAGE_TAB_ENUM.WAIT_CONFIRM && {
      onChange: (keys, rows) => {
        const relRows = []
        rows.forEach(record => {
          const sameOrderList = selectedRows.filter(item => item.orderId === record.orderId)
          /** 相同订单有更早的账单未选中 */
          const isEarlierBillExsistAndNotSelected = sameOrderList.some(
            item =>
              new Date(item.createBillTime).valueOf() < new Date(record.createBillTime).valueOf() &&
              !keys.includes(item.id),
          )
          if (!isEarlierBillExsistAndNotSelected) {
            relRows.push(record)
          }
        })

        toAction({ selectedRows: relRows })
        toAction({ selectedRowKeys: relRows.map(item => item.id) })
      },
      selectedRowKeys,
      getCheckboxProps: record => {
        let disabled = false
        const { nursingAmount = 0, payAmount = 0, payCommission = 0, bindBankAccount, confirmBillTotalAmount } = record
        const sameOrderList = pageList.filter(item => item.orderId === record.orderId)
        /** 相同订单有更早的账单未选中 */
        const isEarlierBillExsistAndNotSelected = sameOrderList.some(
          item =>
            new Date(item.createBillTime).valueOf() < new Date(record.createBillTime).valueOf() &&
            !selectedRowKeys.includes(item.id),
        )
        /** 相同订单的其他已选中账单 */
        const otherBillSelected = sameOrderList.filter(
          item => selectedRowKeys.includes(item.id) && item.id !== record.id,
        )
        /** 其他已选中账单支付费用（护工费用 + 支付手续费） */
        const otherBillSelectedAmount = add(
          ...otherBillSelected.map(({ payCommission, nursingAmount }) => add(payCommission, nursingAmount)),
        )
        if (
          isEarlierBillExsistAndNotSelected ||
          // 订单已支付费用 - 当前账单支付手续费 - 其他已选中账单支付费用 - 已确认订单的账单费用 < 护工费用
          subtract(payAmount, payCommission, otherBillSelectedAmount, confirmBillTotalAmount) < nursingAmount ||
          // 未绑定银行卡
          !bindBankAccount
        ) {
          disabled = true
        }
        return { disabled }
      },
    },
  }

  return (
    <PageLayout
      extraSuffix={
        <div>
          <AekButton
            permissionKey={`${namespace}:confirm`}
            type='primary'
            disabled={!selectedRowKeys.length}
            onClick={() => {
              modal.confirm({
                title: '提示',
                content: '确认账单？',
                onOk: async () => {
                  await requestWithTry(confirmBillApi, { idList: selectedRowKeys })
                  message.success('操作成功')
                  await toAction({ selectedRowKeys: [], selectedRows: [] })
                  await toAction('getPageList')
                },
              })
            }}
          >
            账单确认
          </AekButton>
          <AekButton
            permissionKey={`${namespace}:createBill`}
            type='primary'
            onClick={async () => {
              await CreateBillModal.PromiseThen({})
              toAction('getPageList')
            }}
          >
            手工建账
          </AekButton>
        </div>
      }
    >
      <Tabs
        activeKey={activeKey}
        onChange={onActiveKeyChange}
        className='mb8px'
        items={PCS_BILL_MANAGE_TAB_ENUM.options.map(({ value, label }) => ({
          key: String(value),
          label,
        }))}
      />

      <SearchForm {...searchProps} />
      <AekTable {...tableProps} />
    </PageLayout>
  )
}
export default connect(store => ({
  modelState: store[namespace],
  loading: store.loading,
}))(Index)
